#include <stdio.h>
#include <string.h> // only for bzero
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <stdlib.h>

#include "procReq.h"

#define SERV_PORT 5000
#define PRESIZE 30720 // 262144 = 1024 * 30, max size of a request and infoBody
#define BUFSIZE 2048

message response;
message request;
info data;

int listenFD;

void handle_signal(int sign){
    fputs("\nSIGNAL INTERRUPT\nSAFE EXIT\n", stdout);
    // system("lsof -i:5000");
    // system("kill -9 5000");
    system("netstat");
    close(listenFD);
    exit(0);
}

int main(void) {
    signal(SIGINT,handle_signal);
    // init ==============================//
    preRequest(&request);
    preInfo(&data);
    // ========================== init end //
    struct sockaddr_in servAddr, cliAddr;
    socklen_t cliAddrLen = sizeof(cliAddr);
    int listenFD, conFD;
    int tmpReqLen;
 
    listenFD = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servAddr, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servAddr.sin_port = htons(SERV_PORT);
 
    if (bind(listenFD, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1){
        perror("bind error:");
        exit(1);
    }
    printf("http server listening at port: %d\n", SERV_PORT);
    listen(listenFD, 20);
    
    while(1) {
        conFD = accept(listenFD, (struct sockaddr *)&cliAddr, &cliAddrLen);
        tmpReqLen = read(conFD, request.content, PRESIZE);
        if (tmpReqLen > 0 && tmpReqLen < PRESIZE) request.size = tmpReqLen;
        // procReq =======================================//
        procReq(&request, &response, &data);
        // =================================== procReq end //
        write(conFD, response.content, response.size);
        free(response.content);
        printf("\n-----------------info-------------\n");
        printf("isParameter:%d\trRate:%d\tdRate:%d\terror:%d\tdataLength:%d\n", data.isParameter, data.rRate, data.dRate, data.error, data.dataLength);
        close(conFD);
    }
    close(listenFD);
}